using System;
using Science.Mathematics;
using L=Science.Physics.GeneralPhysics;
using M = Science.Mathematics.Calculus;

namespace Serway.Chapter23
{
	/// <summary>
	/// Example09: The Electric Field of a Uniformly Charged Disk
	/// A disk of radius R has a uniform surface charge density 
	/// \sigma. Calculate the electric field at a point P that
	/// lies along the central perpendicular axis of the disk
	/// and a distance x from the center of the disk.
	/// E_x = 2\pi k_e \sigma ( 1 - x /(x^2 + R^2)^{1/2})	
	/// </summary>
	public class Example09
	{
		public Example09()
		{
		}
		private string result;
		public string Result
		{
			get{return result;}
		}
		double ke = L.Constant.CoulombConstant;
		double sigma  = 10.0; // sigma = Q / (Math.PI R^2)
		double R = 2.0;
		double x = 3.0;
		double y = 0.00000000001;
		double z = 0.00000000001;
		L.Position r = new L.Position();
		L.Position rp = new L.Position();
		public void Compute()
		{
			rp.X = x;
			rp.Y = y;
			rp.Z = z;

			Function.DoubleAToDouble Ex
				= new Function.DoubleAToDouble(funcx);
			M.IntegrationMultiD projx = new M.IntegrationMultiD(Ex);
			double[] r = {0.0,0.0};
			projx.From = r;
			double[] rt = {R, 2.0*Math.PI};
			projx.To = rt;
			projx.Compute();

			Function.DoubleAToDouble Ey
				= new Function.DoubleAToDouble(funcy);
			M.IntegrationMultiD projy = new M.IntegrationMultiD(Ey);
    		projy.From = r;
			projy.To = rt;
			projy.Compute();

			Function.DoubleAToDouble Ez
				= new Function.DoubleAToDouble(funcz);
			M.IntegrationMultiD projz = new M.IntegrationMultiD(Ez);
			projz.From = r;
			projz.To = rt;
			projz.Compute();

			result+=Convert.ToString(projx.BestEstimation)+"  i + ";  
			result+=Convert.ToString(projy.BestEstimation)+"  j + ";  
			result+=Convert.ToString(projz.BestEstimation)+"  k \r\n ";  
			result+=Convert.ToString(2.0*Math.PI*ke*sigma
				*(1.0 - x /Math.Sqrt(x*x + R*R)));  
		}
		private double funcx(double[] rtheta)
		{
			r.X = 0.0;
			r.Y = rtheta[0]*Math.Cos(rtheta[1]);
			r.Z = rtheta[0]*Math.Sin(rtheta[1]);
			
			L.ElectricCharge q = new L.ElectricCharge();
			q.C = sigma*rtheta[0];
			L.ElectricField E = new L.ElectricField(q,r,rp);
			return E.X;
		}
		private double funcy(double[] rtheta)
		{
			r.X = 0.0;
			r.Y = rtheta[0]*Math.Cos(rtheta[1]);
			r.Z = rtheta[0]*Math.Sin(rtheta[1]);
			
			L.ElectricCharge q = new L.ElectricCharge();
			q.C = sigma*rtheta[0];
			L.ElectricField E = new L.ElectricField(q,r,rp);
			return E.Y;
		}
		private double funcz(double[] rtheta)
		{
			r.X = 0.0;
			r.Y = rtheta[0]*Math.Cos(rtheta[1]);
			r.Z = rtheta[0]*Math.Sin(rtheta[1]);
			
			L.ElectricCharge q = new L.ElectricCharge();
			q.C = sigma*rtheta[0];
			L.ElectricField E = new L.ElectricField(q,r,rp);
			return E.Z;
		}
	}
}
